"  _____                              _ __  __ 
" |  ___|_ _ _ __   ___ _   _  __   _(_)  \/  |
" | |_ / _` | '_ \ / __| | | | \ \ / / | |\/| |
" |  _| (_| | | | | (__| |_| |  \ V /| | |  | |
" |_|  \__,_|_| |_|\___|\__, |   \_/ |_|_|  |_|
"                       |___/                  
"==============================================
" Name: Fancy vim
" Author: @HAo99(Harvey Leung)
" Version: 1.0.0
"  _   _                            
" | | | | __ _ _ ____   _____ _   _ 
" | |_| |/ _` | '__\ \ / / _ \ | | |
" |  _  | (_| | |   \ V /  __/ |_| |
" |_| |_|\__,_|_|    \_/ \___|\__, |
"                             |___/ 
" =========== Design By Harvey Leung.


" ==========================
" =  Plugins Installation  =
" ==========================
call plug#begin('~/.config/nvim/plugged')

" Auto Completion
Plug 'neoclide/coc.nvim', {'branch': 'release'}

" Beautify
Plug 'vim-airline/vim-airline'              " Vim Status Line
Plug 'vim-airline/vim-airline-themes'       " Vim Status Line Themes
Plug 'luochen1990/rainbow'

Plug 'joshdick/onedark.vim'                 " Vim Color Scheme
Plug 'ayu-theme/ayu-vim'
Plug 'mhinz/vim-startify'                   " Welcome Page
Plug 'mhinz/vim-signify'                    " Show Changes
"Plug 'bling/vim-bufferline'                 " Show Buffer In Status Line
"Plug 'mg979/vim-xtabline'                   " Vim Tab Title Line
Plug 'wincent/terminus'                     " Enhanced terminal integration for Vim
Plug 'ryanoasis/vim-devicons'
Plug 'morhetz/gruvbox'
Plug 'rakr/vim-one'

" Enhance
Plug 'RRethy/vim-illuminate'                " Highlight Selected Word
Plug 'liuchengxu/vista.vim'                 " Vim Tag List, Show Func/Class
Plug 'dhruvasagar/vim-table-mode'
" Plug 'majutsushi/tagbar' 
Plug 'tomtom/tcomment_vim'
" Plug 'h-youhei/vim-ibus'
Plug 'voldikss/vim-floaterm'
" Plug 'ctrlpvim/ctrlp.vim'
Plug 'jiangmiao/auto-pairs'                 " Auto Pairs
Plug 'kevinhwang91/rnvimr', {'do': 'make sync'}
Plug 'airblade/vim-rooter'
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
Plug 'easymotion/vim-easymotion'
Plug 'vimwiki/vimwiki'


" Snippets
" Plug 'SirVer/ultisnips'
Plug 'theniceboy/vim-snippets'
Plug 'junegunn/goyo.vim'


" Language Support
Plug 'fatih/vim-go', { 'do': ':GoUpdateBinaries' }
Plug 'alvan/vim-closetag'

" Auto Format
Plug 'Chiel92/vim-autoformat'

call plug#end()

" =====================
" =  Vim Raw Setting  =
" =====================

syntax on
set background=light
" let ayucolor="light"
" let ayucolor="mirage" " for mirage version of theme
" let ayucolor="dark"   " for dark version of theme
colorscheme one
"let g:airline_theme='one'

" Some servers have issues with backup files
set nobackup
set nowritebackup

" Give more space for displaying message.
set cmdheight=1

" Having longer updatetime (default is 4000 ms = 4 s) leads to noticeable
" delays and poor user experience
set updatetime=100

set hidden

set signcolumn=yes

" enable true colors support
set termguicolors
let $NVIM_TUI_ENABLE_TRUE_COLOR=1

" show line number
set number 
set cursorline
set tabstop=4
set shiftwidth=4
set softtabstop=4
set smartcase
set lazyredraw
set expandtab
set textwidth=0

set autoindent

set list

set noshowmode

set ttyfast

noremap H 5h
noremap L 5l
noremap J 5j
noremap K 5k

let mapleader=" "    " Set <LEADER> as <SPACE>

noremap Q :q<CR>
noremap S :w<CR>
noremap ; :
noremap tl :bn<CR>
noremap th :bp<CR>
noremap <C-w> :bd<CR>

autocmd FileType php,python,c,java,perl,shell,bash,vim,ruby,cpp set ai
autocmd FileType php,python,c,java,perl,shell,bash,vim,ruby,cpp set sw=4
autocmd FileType php,python,c,java,perl,shell,bash,vim,ruby,cpp set ts=4
autocmd FileType php,python,c,java,perl,shell,bash,vim,ruby,cpp set sts=4
autocmd FileType javascript,html,css,xml,vue set ai
autocmd FileType javascript,html,css,xml,vue set sw=2
autocmd FileType javascript,html,css,xml,vue set ts=2
autocmd FileType javascript,html,css,xml,vue set sts=2

" ========================
" =  Windows Management  =
" ========================
noremap <LEADER>w <C-w>w
noremap <LEADER>k <C-w>k
noremap <LEADER>h <C-w>h
noremap <LEADER>j <C-w>j
noremap <LEADER>l <C-w>l

noremap s <nop>
noremap su :set nosplitbelow<CR>:split<CR>:set splitbelow<CR>
noremap se :set splitbelow<CR>:split<CR>
noremap sn :set nosplitright<CR>:vsplit<CR>:set splitright<CR>
noremap si :set splitright<CR>:vsplit<CR>

noremap <up> :res +5<CR>
noremap <down> :res -5<CR>
noremap <left> :vertical resize-5<CR>
noremap <right> :vertical resize+5<CR>

" ====================
" =  Tab Management  =
" ====================
" noremap tt :XTabMode<CR>
" create a new tab
noremap <LEADER>tn :tabe<CR>
" switch tabs
noremap <LEADER>th :-tabnext<CR>
noremap <LEADER>tl :+tabnext<CR>
" move tabs
noremap <LEADER>tmh :-tabmove<CR>
noremap <LEADER>tml :+tabmove<CR>


" ===================================
" =  Command Mode Cursor Movement  ==
" ===================================
cnoremap <C-a> <Home>
cnoremap <C-e> <End>
inoremap <C-l> <ESC>A

" =====================
" =  Tab size switch  =
" =====================
noremap <LEADER><TAB>2 :set tabstop=2<CR>:set shiftwidth=2<CR>:set softtabstop=2<CR>
noremap <LEADER><TAB>4 :set tabstop=4<CR>:set shiftwidth=4<CR>:set softtabstop=4<CR>


" ===============================
" = Compile Func & Key Binding  =
" ===============================
noremap <LEADER>b :call CompileRunGcc()<CR>
func! CompileRunGcc()
	exec "w"
	if &filetype == 'c'
		exec "!g++ % -o %<"
"		exec "!time ./%<"
	elseif &filetype == 'cpp'
		set splitbelow
		exec "!g++ -std=c++11 % -Wall -o %<"
		:sp
		:res -10
"		:term ./%<
	elseif &filetype == 'java'
		exec "!javac %"
"		exec "!time java %<"
"	elseif &filetype == 'sh'
"		:!time bash %
"	elseif &filetype == 'python'
"		set splitbelow
"		:sp
"		:term python3 %
	elseif &filetype == 'dart'
		CocCommand flutter.run -d iPhone\ 11\ Pro
		CocCommand flutter.dev.openDevLog
	elseif &filetype == 'javascript'
		set splitbelow
		:sp
"		:term export DEBUG="INFO,ERROR,WARNING"; node --trace-warnings .
	elseif &filetype == 'go'
		set splitbelow
		:sp
"		:term go run .
	endif
endfunc






" ==================
" =  Coc Settings  =
" ==================
let g:coc_global_extensions = ['coc-go', "coc-prettier", "coc-json", "coc-css", "coc-explorer", "coc-html", "coc-snippets", "coc-clangd", "coc-xml", "coc-vetur", "coc-tsserver", "coc-python", "coc-vimlsp", "coc-yaml", "coc-emmet", "coc-syntax", "coc-java"]

function! s:check_back_space() abort
	let col = col('.') - 1
	return !col || getline('.')[col - 1]	=~ '\s'
endfunction
inoremap <silent><expr> <TAB>
	\ pumvisible() ? "\<C-n>" :
	\ <SID>check_back_space() ? "\<TAB>" :
	\ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
inoremap <expr> <cr> complete_info()["selected"] != "-1" ? "\<C-y>" : "\<C-g>u\<CR>"
function! s:check_back_space() abort
	let col = col('.') - 1
	return !col || getline('.')[col - 1]  =~# '\s'
endfunction

inoremap <silent><expr> <c-space> coc#refresh()
inoremap <silent><expr> <c-o> coc#refresh()

nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)
nmap <silent> rn <Plug>(coc-rename)

nnoremap <silent> E :call <SID>show_documentation()<CR>

function! s:show_documentation()
  if (index(['vim','help'], &filetype) >= 0)
    execute 'h '.expand('<cword>')
  else
    call CocAction('doHover')
  endif
endfunction

" coc-explorer config
nmap <LEADER>e :CocCommand explorer<CR>


" =========================
" =  Illuminate Settings  =
" =========================
let g:Illuminate_delay = 250


" =======================
" =  Snippets Settings  =
" =======================
" let g:UltiSnipsExpandTrigger="<C-j>"
" let g:UltiSnipsJumpForwardTrigger="<C-j>"
" let g:UltiSnipsJumpBackwardTrigger="<C-k>"
imap <C-j> <Plug>(coc-snippets-expand)

vmap <C-j> <Plug>(coc-snippets-select)

let g:coc_snippet_next = '<c-j>'
let g:coc_snippet_prev = '<c-k>'
imap <C-j> <Plug>(coc-snippets-expand-jump)

" =====================
" = Tag Bar Settings  =
" =====================
nmap <LEADER>t :Vista!!<CR>
let g:vista_default_executive = 'coc'
let g:vista_icon_indent = ["╰─▸ ", "├─▸ "]
let g:vista_fzf_preview = ['right:50%']
let g:vista#renderer#enable_icon = 1
let g:vista#renderer#icons = {
\   "function": "\uf794",
\   "variable": "\uf71b",
\  }
function! NearestMethodOrFunction() abort
	return get(b:, 'vista_nearest_method_or_function', '')
endfunction
set statusline+=%{NearestMethodOrFunction()}
autocmd VimEnter * call vista#RunForNearestMethodOrFunction()

let g:bufferline_echo = 0

" =============================
" =  Tab Title Line Setting  ==
" =============================
let g:xtabline_settings = {}
let g:xtabline_settings.enable_mappings = 0
let g:xtabline_settings.tabline_modes = ['tabs', 'buffers']
let g:xtabline_settings.enable_persistance = 0
let g:xtabline_settings.last_open_first = 1



" =============================
" =  Rainbow Bracket Setting  =
" =============================
let g:rainbow_active = 1


" ====================
" =  Rnvimr Setting  =
" ====================
noremap <LEADER>r :RnvimrToggle<CR>

let g:rnvimr_ex_enable = 1
let g:rnvimr_pick_enable = 1

" ====================
" =  Rooter Setting  =
" ====================
let g:rooter_patterns = ['__vim_project_root', '.git/']


" ==========================
" =  tcomment_vim Setting  =
" ==========================
nnoremap ci cl
let g:tcomment_textobject_inlinecomment = ''
nmap <LEADER>cn g>c
vmap <LEADER>cn g>
nmap <LEADER>cu g<c
vmap <LEADER>cu g<


" ====================
" =  Vim-go Setting  =
" ====================
let g:go_echo_go_info = 0
let g:go_doc_popup_window = 1
let g:go_def_mapping_enabled = 0
let g:go_template_autocreate = 0
let g:go_textobj_enabled = 0
let g:go_auto_type_info = 1
let g:go_def_mapping_enabled = 0
let g:go_highlight_array_whitespace_error = 1
let g:go_highlight_build_constraints = 1
let g:go_highlight_chan_whitespace_error = 1
let g:go_highlight_extra_types = 1
let g:go_highlight_fields = 1
let g:go_highlight_format_strings = 1
let g:go_highlight_function_calls = 1
let g:go_highlight_function_parameters = 1
let g:go_highlight_functions = 1
let g:go_highlight_generate_tags = 1
let g:go_highlight_methods = 1
let g:go_highlight_operators = 1
let g:go_highlight_space_tab_error = 1
let g:go_highlight_string_spellcheck = 1
let g:go_highlight_structs = 1
let g:go_highlight_trailing_whitespace_error = 1
let g:go_highlight_types = 1
let g:go_highlight_variable_assignments = 0
let g:go_highlight_variable_declarations = 0
let g:go_doc_keywordprg_enabled = 0

" ================================
" =  Floating Termainal Setting  =
" ================================
noremap <LEADER>` :FloatermToggle<CR>


" ======================
" =  Airline Settings  =
" ======================
let g:airline#extensions#tabline#enabled = 1
let g:airline_powerline_fonts = 1

" ====================
" =  CtrlP Settings  =
" ====================
" let g:ctrlp_working_path_mode = 'ra'
" let g:ctrlp_map = '<c-p>'
" let g:ctrlp_cmd = 'CtrlP'

" ==================
" =  Fzf Settings  =
" ==================
noremap <C-p> :Files<CR>
" noremap <C-f> :Rg<CR>
noremap <C-h> :History<CR>
"noremap <C-t> :BTags<CR>
noremap <C-l> :Lines<CR>
" noremap <C-w> :Buffers<CR>
noremap <leader>; :History:<CR>

let g:fzf_preview_window = 'right:60%'
let g:fzf_commits_log_options = '--graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"'

function! s:list_buffers()
  redir => list
  silent ls
  redir END
  return split(list, "\n")
endfunction

function! s:delete_buffers(lines)
  execute 'bwipeout' join(map(a:lines, {_, line -> split(line)[0]}))
endfunction

command! BD call fzf#run(fzf#wrap({
  \ 'source': s:list_buffers(),
  \ 'sink*': { lines -> s:delete_buffers(lines) },
  \ 'options': '--multi --reverse --bind ctrl-a:select-all+accept'
\ }))

noremap <c-d> :BD<CR>

let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.7 } }

" ======================
" =  Vim Ibus Setting  =
" ======================
" let g:ibus#layout = 'xkb:us::eng'
" let g:ibus#engine = 'rime'
"

nnoremap \f :Autoformat<CR>

let g:EasyMotion_do_mapping = 0
let g:EasyMotion_do_shade = 0
let g:EasyMotion_smartcase = 1
map ' <Plug>(easymotion-bd-f)
nmap ' <Plug>(easymotion-bd-f)
